/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.easoft.code.pos.ui.beans;

import com.easoft.code.pos.App;
import com.easoft.code.pos.data.exception.CoreDataLayerException;
import com.easoft.code.pos.data.pojos.Persona;
import com.easoft.code.pos.data.pojos.PosFactura;
import com.easoft.code.pos.data.pojos.PosUsuario;
import com.easoft.code.pos.data.pojos.Precio;
import com.easoft.code.pos.data.pojos.Producto;
import com.easoft.code.pos.ui.beans.pos.POSItem;
import com.easoft.code.pos.ui.beans.pos.POSOperation;
import com.easoft.code.pos.ui.controllers.POSController;
import com.easoft.code.pos.ui.models.PojoTableModel;
import com.easoft.code.pos.util.DataFormatter;
import com.easoft.code.pos.util.UIUtil;
import com.easoft.code.pos.util.Valores;
import java.awt.HeadlessException;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

/**
 *
 * @author Eliu
 */
public class FormPOS extends javax.swing.JPanel {

    private PojoTableModel productsModel;
    private POSController controller = new POSController();
    private static POSOperation currentOperation = new POSOperation();
    private static List<POSOperation> histOperations = new LinkedList<>();
    private Persona cliente;

    /**
     * Creates new form FormPOS
     */
    public FormPOS() {
        initComponents();
        initPOS();
    }

    private void initPOS() {
        productsModel = new PojoTableModel(new LinkedList<POSItem>(),
                Arrays.asList(new String[]{"Codigo", "Descripcion", "Precio", "Cantidad", "Descuento Man. x Unidad", "Descuento Auto. x Unidad", "Subtotal"}),
                Arrays.asList(new String[]{"CodProducto", "NombreProducto", "Precio", "Cantidad", "DescuentoManual", "DescuentoAuto", "Subtotal"}),
                POSItem.class);
        currentOperation = new POSOperation();
        gridProductos.setModel(productsModel);
        productsModel.fireTableDataChanged();
        cantProductos.setText("0");
        subtotalFact.setText("0.00");
        totalDescuento.setText("0.00");
    }

    private void modProductCantidad(Double cantidad) {
        if (cantidad <= 0) {
            UIUtil.showError("Cantidad menor o igual a cero", "Cantidad");
        }
        POSItem item = (POSItem) productsModel.getData().get(gridProductos.getSelectedRow());
        item.setCantidad(cantidad);
        item.setSubtotal(item.getCantidad() * item.getPrecio());

        productsModel.fireTableDataChanged();
    }

    private Double getProductDescManual() {
        if (gridProductos.getSelectedRow() >= 0) {
            POSItem item = (POSItem) productsModel.getData().get(gridProductos.getSelectedRow());
            return item.getDescuentoManual();
        }
        return 0d;
    }

    private Double getProductCant() {
        POSItem item = (POSItem) productsModel.getData().get(gridProductos.getSelectedRow());
        return item.getCantidad();
    }

    private void modProductDescuento(Double descuento, PosUsuario uAut) {
        if (descuento <= 0) {
            UIUtil.showError("Descuento invalida!", "Cantidad");
        }
        POSItem item = (POSItem) productsModel.getData().get(gridProductos.getSelectedRow());
        item.setUsuarioAut(uAut);
        if (descuento > item.getSubtotal()) {
            UIUtil.showError("Descuento mayor al valor facturado de producto!", "Cantidad");
            return;
        }
        item.setDescuentoManual(descuento);
        item.setSubtotal(item.getSubtotal() - descuento);
        productsModel.fireTableDataChanged();
    }

    private void refreshStatusBar() {
        double descuento = 0d;
        double subtotal = 0d;
        double cantproducto = 0d;
        for (Iterator i = productsModel.iterator(); i.hasNext();) {
            POSItem it = (POSItem) i.next();
            descuento = descuento + (it.getDescuentoAuto() * it.getCantidad()) + it.getDescuentoManual();
            subtotal = subtotal + it.getSubtotal();
            cantproducto = cantproducto + it.getCantidad();
        }
        totalDescuento.setText(DataFormatter.formatNumber(descuento));
        subtotalFact.setText(DataFormatter.formatNumber(subtotal));
        cantProductos.setText(DataFormatter.formatNumber(cantproducto));

        currentOperation.setItems(productsModel.getData());
        currentOperation.setCliente(cliente);
        currentOperation.setTotal(subtotal);
        currentOperation.setDescuento(descuento);
    }

    private void removeItem() {
        productsModel.getData().remove(gridProductos.getSelectedRow());
        productsModel.fireTableDataChanged();
    }

    private void addPOSItem(Producto p) {
        POSItem i = new POSItem(p, getProductoPrecio(p), 1d);
        productsModel.getData().add(i);
        productsModel.fireTableDataChanged();
    }

    /**
     * determina el precio de un producto
     *
     * @param p
     * @return
     */
    private Double getProductoPrecio(Producto p) {
        if (p.getPrecioCollection() != null && !p.getPrecioCollection().isEmpty()) {
            for (Precio pr : p.getPrecioCollection()) {
                if (Valores.PRECIO_POS == pr.getTipoPrecio().intValue()) {
                    Double valor = (Double) (pr.getTipoRecargo() == Valores.PRECIO_RECARGO_PORC
                            ? (p.getPrecioCosto().doubleValue() * (1 + pr.getRecargo() / 100))
                            : (p.getPrecioCosto().doubleValue() + pr.getRecargo() / 100));
                    return Double.parseDouble(DataFormatter.formatNumber(valor));
                }
            }
        }

        return p.getPrecioCosto().doubleValue();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        header = new javax.swing.JPanel();
        header1 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        codigoProducto = new javax.swing.JTextField();
        btnBuscar = new javax.swing.JButton();
        btnSearch = new javax.swing.JButton();
        header2 = new javax.swing.JPanel();
        btnNuevaFact = new javax.swing.JButton();
        btnGuardar = new javax.swing.JButton();
        btnCliente = new javax.swing.JButton();
        btnSuspender = new javax.swing.JButton();
        btnCargarFact = new javax.swing.JButton();
        body = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        gridProductos = new javax.swing.JTable();
        jPanel1 = new javax.swing.JPanel();
        btnModCant = new javax.swing.JButton();
        btnAddDesc = new javax.swing.JButton();
        btnQuitarProd = new javax.swing.JButton();
        footer = new javax.swing.JPanel();
        footer1 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();
        cantProductos = new javax.swing.JLabel();
        footer4 = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        subtotalFact = new javax.swing.JLabel();
        footer5 = new javax.swing.JPanel();
        jLabel6 = new javax.swing.JLabel();
        totalDescuento = new javax.swing.JLabel();

        setLayout(new java.awt.BorderLayout());

        header.setMinimumSize(new java.awt.Dimension(40, 30));
        header.setLayout(new java.awt.GridLayout(1, 0));

        header1.setMinimumSize(new java.awt.Dimension(170, 35));
        header1.setPreferredSize(new java.awt.Dimension(300, 40));
        header1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 1, 5));

        jLabel1.setText("Codigo Producto");
        header1.add(jLabel1);

        codigoProducto.setPreferredSize(new java.awt.Dimension(150, 30));
        codigoProducto.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                codigoProductoActionPerformed(evt);
            }
        });
        codigoProducto.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                codigoProductoFocusGained(evt);
            }
        });
        codigoProducto.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                codigoProductoKeyPressed(evt);
            }
        });
        header1.add(codigoProducto);

        btnBuscar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/add-4.png"))); // NOI18N
        btnBuscar.setText("Agregar");
        btnBuscar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnBuscarActionPerformed(evt);
            }
        });
        header1.add(btnBuscar);

        btnSearch.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/search-10.png"))); // NOI18N
        btnSearch.setText("Buscar");
        btnSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSearchActionPerformed(evt);
            }
        });
        header1.add(btnSearch);

        header.add(header1);

        header2.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT));

        btnNuevaFact.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/icon-16-new.png"))); // NOI18N
        btnNuevaFact.setText("Nueva");
        btnNuevaFact.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnNuevaFactActionPerformed(evt);
            }
        });
        header2.add(btnNuevaFact);

        btnGuardar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/tick.png"))); // NOI18N
        btnGuardar.setText("Guardar");
        btnGuardar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnGuardarActionPerformed(evt);
            }
        });
        header2.add(btnGuardar);

        btnCliente.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/user.png"))); // NOI18N
        btnCliente.setText("Cliente");
        btnCliente.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnClienteActionPerformed(evt);
            }
        });
        header2.add(btnCliente);

        btnSuspender.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/player-pause.png"))); // NOI18N
        btnSuspender.setText("Suspender");
        btnSuspender.setEnabled(false);
        btnSuspender.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSuspenderActionPerformed(evt);
            }
        });
        header2.add(btnSuspender);

        btnCargarFact.setText("Cargar ");
        btnCargarFact.setEnabled(false);
        btnCargarFact.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCargarFactActionPerformed(evt);
            }
        });
        header2.add(btnCargarFact);

        header.add(header2);

        add(header, java.awt.BorderLayout.PAGE_START);

        body.setLayout(new java.awt.BorderLayout());

        gridProductos.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        gridProductos.setRowHeight(20);
        gridProductos.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jScrollPane1.setViewportView(gridProductos);

        body.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

        btnModCant.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/edit-9.png"))); // NOI18N
        btnModCant.setText("Cantidad");
        btnModCant.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnModCantActionPerformed(evt);
            }
        });
        jPanel1.add(btnModCant);

        btnAddDesc.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/money-2.png"))); // NOI18N
        btnAddDesc.setText("Descuento");
        btnAddDesc.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddDescActionPerformed(evt);
            }
        });
        jPanel1.add(btnAddDesc);

        btnQuitarProd.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/icon-16-delete.png"))); // NOI18N
        btnQuitarProd.setText("Quitar");
        btnQuitarProd.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnQuitarProdActionPerformed(evt);
            }
        });
        jPanel1.add(btnQuitarProd);

        body.add(jPanel1, java.awt.BorderLayout.PAGE_START);

        add(body, java.awt.BorderLayout.CENTER);

        footer.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 15, 5));

        footer1.setLayout(new java.awt.GridLayout(2, 1));

        jLabel2.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        jLabel2.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel2.setText("Cantida Productos");
        footer1.add(jLabel2);

        cantProductos.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        cantProductos.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        cantProductos.setText("0.00");
        footer1.add(cantProductos);

        footer.add(footer1);

        footer4.setLayout(new java.awt.GridLayout(2, 1));

        jLabel4.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        jLabel4.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel4.setText("Total Factura");
        footer4.add(jLabel4);

        subtotalFact.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        subtotalFact.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        subtotalFact.setText("0.00");
        footer4.add(subtotalFact);

        footer.add(footer4);

        footer5.setLayout(new java.awt.GridLayout(2, 1));

        jLabel6.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel6.setText("Total Ahorro");
        footer5.add(jLabel6);

        totalDescuento.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        totalDescuento.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        totalDescuento.setText("0.00");
        footer5.add(totalDescuento);

        footer.add(footer5);

        add(footer, java.awt.BorderLayout.PAGE_END);
    }// </editor-fold>//GEN-END:initComponents

    private void btnSuspenderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSuspenderActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_btnSuspenderActionPerformed

    private void btnClienteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClienteActionPerformed
        FormPOSDatosCliente frmCliente = new FormPOSDatosCliente(controller, cliente);
        cliente = frmCliente.getCliente();
    }//GEN-LAST:event_btnClienteActionPerformed

    private void btnNuevaFactActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnNuevaFactActionPerformed
        if (!currentOperation.isCompletado()) {
            if (UIUtil.confirm("La factura actual no esta guardada desea hacerlo?", "Factura No Guardad")) {
                btnGuardarActionPerformed(null);
            }
        }
        initPOS();

    }//GEN-LAST:event_btnNuevaFactActionPerformed

    private void btnCargarFactActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCargarFactActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_btnCargarFactActionPerformed

    private void codigoProductoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_codigoProductoActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_codigoProductoActionPerformed

    private void btnBuscarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnBuscarActionPerformed
        try {
            if (cliente == null) {
                FormPOSDatosCliente frmCliente = new FormPOSDatosCliente(controller, null);
                cliente = frmCliente.getCliente();
            }
            Producto p = new Producto();
            p.setCodigo(codigoProducto.getText());
            p = controller.getProductoByCodigo(p);
            if (p != null) {
                addPOSItem(p);
                refreshStatusBar();
            } else {
                UIUtil.showError("El producto no existe!", "Productos");
            }

        } catch (CoreDataLayerException ex) {
            Logger.getLogger(FormPOS.class.getName()).log(Level.SEVERE, null, ex);
        }
        codigoProducto.setText("");

    }//GEN-LAST:event_btnBuscarActionPerformed

    private void codigoProductoKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_codigoProductoKeyPressed
        if (evt.getKeyCode() == 10) {
            btnBuscarActionPerformed(null);
        }
    }//GEN-LAST:event_codigoProductoKeyPressed

    private void codigoProductoFocusGained(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_codigoProductoFocusGained
        //TODO: nothing
    }//GEN-LAST:event_codigoProductoFocusGained

    private void btnGuardarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGuardarActionPerformed
        FormPOSFormaPago pago = new FormPOSFormaPago(currentOperation);
        currentOperation = pago.getOperation();
        if (currentOperation.isCompletado()) {
            try {
                PosFactura fac = controller.saveOperation(currentOperation);
                /*
                 Printer.printReport("ImpFactura", fac.getPosFacturaPK().getSerie(), fac.getPosFacturaPK().getNumero(),
                 NumberToLetterConverter.convertNumberToLetter(fac.getTotal()));*/
                initPOS();
            } catch (CoreDataLayerException ex) {
                ex.printStackTrace(System.err);
                UIUtil.showError(ex.getMessage(), "Error Guardando!");
            }
        }
    }//GEN-LAST:event_btnGuardarActionPerformed

    private void btnModCantActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnModCantActionPerformed
        try {
            String s = (String) JOptionPane.showInputDialog(
                    App.mainForm,
                    "Ingrese la nueva cantidad!",
                    "Modificacion Cantidad",
                    JOptionPane.PLAIN_MESSAGE, null, null, getProductCant());

            modProductCantidad(Double.valueOf(s));
        } catch (HeadlessException | NumberFormatException e) {
            UIUtil.showError("Cantidad invalida!", "Cantida Producto");
        }
        refreshStatusBar();
    }//GEN-LAST:event_btnModCantActionPerformed

    private void btnAddDescActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddDescActionPerformed
        try {
            String s = (String) JOptionPane.showInputDialog(
                    App.mainForm,
                    "Ingrese valor de descuento!",
                    "Aplicar Descuento",
                    JOptionPane.PLAIN_MESSAGE, null, null, getProductDescManual());
            if (s != null && !s.isEmpty() && Double.parseDouble(s) > 0) {
                FormAutoriza aut = new FormAutoriza(App.mainForm, true);
                if (aut.isDatosValidos()) {
                    modProductDescuento(Double.valueOf(s), aut.getUsuario());
                }
            }
        } catch (HeadlessException | NumberFormatException e) {
            UIUtil.showError("Descuento invalido. " + e.getMessage(), "Descuento");
        }
        refreshStatusBar();
    }//GEN-LAST:event_btnAddDescActionPerformed

    private void btnQuitarProdActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuitarProdActionPerformed
        if (UIUtil.confirm(
                "Esta seguro de quitarlo?",
                "Producto")) {
            removeItem();
            refreshStatusBar();
        }
    }//GEN-LAST:event_btnQuitarProdActionPerformed

    private void btnSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSearchActionPerformed
        FormPOSBusquedaProds b = new FormPOSBusquedaProds();
        if (b.getSelProduct() != null) {
            if (cliente == null) {
                FormPOSDatosCliente frmCliente = new FormPOSDatosCliente(controller, null);
                cliente = frmCliente.getCliente();
            }
            addPOSItem(b.getSelProduct());
            refreshStatusBar();
        }
    }//GEN-LAST:event_btnSearchActionPerformed
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel body;
    private javax.swing.JButton btnAddDesc;
    private javax.swing.JButton btnBuscar;
    private javax.swing.JButton btnCargarFact;
    private javax.swing.JButton btnCliente;
    private javax.swing.JButton btnGuardar;
    private javax.swing.JButton btnModCant;
    private javax.swing.JButton btnNuevaFact;
    private javax.swing.JButton btnQuitarProd;
    private javax.swing.JButton btnSearch;
    private javax.swing.JButton btnSuspender;
    private javax.swing.JLabel cantProductos;
    private javax.swing.JTextField codigoProducto;
    private javax.swing.JPanel footer;
    private javax.swing.JPanel footer1;
    private javax.swing.JPanel footer4;
    private javax.swing.JPanel footer5;
    private javax.swing.JTable gridProductos;
    private javax.swing.JPanel header;
    private javax.swing.JPanel header1;
    private javax.swing.JPanel header2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel subtotalFact;
    private javax.swing.JLabel totalDescuento;
    // End of variables declaration//GEN-END:variables
}
